package common.service;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import util.DateUtil;
import util.DebugUtil;
import util.StringUtil;
import util.idgenerator.IDGeneratorUtil;
import wf.IWorkFlowService;
import wf.WorkFlowService;

import common.dao.connection.ConnectionProviderFactory;
import common.dao.connection.IConnectionProvider;
import common.serialization.IWebText;
import common.serialization.JsonWebText;
import common.serialization.StringWebText;
import common.serialization.XmlDataBean;
import common.splitpage.Condition;
import common.splitpage.JdbcPageImpl;
import common.splitpage.PageInfo;
import common.splitpage.Pageable;
import common.web.WebHelper;
import common.web.action.BaseAction;

public class BaseService implements IService {
	private static Logger logger = Logger.getLogger(BaseService.class.getName());
	
	private Object proxyObj; // Session代理   or Connection代理
	
	private boolean isNest = false;   //是否嵌套事务,默认为否
	
	private WebHelper webHelper;//获取request、session等web信息
	
	private String tableName = "";
	private String conditionSql = "";
	private String orderSql = "";
	public boolean getNestTransaction() {
		return isNest;
	}
	public void setNestTransaction(boolean isNest) {
		this.isNest = isNest;
	}
	
	public WebHelper getWebHelper() {
		return webHelper;
	}
	public void setWebHelper(WebHelper webHelper) {
		this.webHelper = webHelper;
	}
	
	public void setProxyObj(Object obj) {
		proxyObj = obj;
	}

	public String getConditionSql() {
		return conditionSql;
	}
	public void setConditionSql(String conditionSql) {
		this.conditionSql = conditionSql;
	}
	public String getOrderSql() {
		return orderSql;
	}
	public void setOrderSql(String orderSql) {
		this.orderSql = orderSql;
	}
	public String getTableName() {
		return tableName;
	}
	public void setTableName(String tableName) {
		this.tableName = tableName;
	}
	
	protected Connection getConnection() throws Exception {
		if(proxyObj == null) {//如果没有设置代理就重新获取连接
			IConnectionProvider connectionProvider = ConnectionProviderFactory.getConnectionProvider();
			proxyObj = connectionProvider.getConnection();
		}
		return (Connection) proxyObj;
	}
	
	protected void close(ResultSet rs, PreparedStatement ps, Connection conn) throws Exception {
		if(rs != null) rs.close();
		if(ps != null) ps.close();
		if(conn != null) conn.close();
	}
	
	//获取当前service的代理类
	protected IService getThisServiceProxy() {
		IService service = ServiceFactory.getService(this);
		service.setWebHelper(this.getWebHelper());
		return service;
	}
	
	//根据sql语句更新数据
	public int executeBySql(String sql) throws Exception {
		int rowCount = 0;
		Connection conn = null;
		try {
			conn = this.getConnection();
			conn.setAutoCommit(false);//需要设置为false才能回滚,为了不用代理的时候也能生效
			rowCount = conn.createStatement().executeUpdate(sql);
			conn.commit();
		} catch(Exception e){
			e.printStackTrace();
			conn.rollback();
			throw new Exception(e);
		}finally {
			conn.close();
		}	
		return rowCount;
	}
	
	public int executeBySql(String sql,Object[] parameters) throws Exception {
		int rowCount = 0;
		
		Connection conn = null;
		PreparedStatement pstm = null;
		try {
			conn = this.getConnection();
			conn.setAutoCommit(false);//需要设置为false才能回滚,为了不用代理的时候也能生效
			pstm = conn.prepareStatement(sql);
			if(parameters != null) {
				this.setParameters(pstm, parameters);
			}
			rowCount = pstm.executeUpdate();
			conn.commit();
		} catch(Exception e){
			e.printStackTrace();
			conn.rollback();
			throw new Exception(e);
		}finally {
			this.close(null, pstm, conn);
		}
		return rowCount;
	}
	
	//根据sql语句更新数据
	public int[] executeBySql(String[] sqlArr) throws Exception {
		int[] rowCountArr = new int[sqlArr.length];
		Connection conn = null;
		try {
			conn = this.getConnection();
			conn.setAutoCommit(false);//需要设置为false才能回滚,为了不用代理的时候也能生效
			for(int i = 0;i<sqlArr.length;i++) {
				rowCountArr[i] = conn.createStatement().executeUpdate(sqlArr[i]);
			}
			conn.commit();
		} catch(Exception e){
			e.printStackTrace();
			conn.rollback();
			throw new Exception(e);
		}finally {
			conn.close();
		}	
		return rowCountArr;
	}
	
	//根据sql语句批量更新数据
	public int[] executeBatchBySql(String sql, List<Object[]> parameterList) throws Exception {
		int[] rowCountArr = null;
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			conn = this.getConnection();
			conn.setAutoCommit(false);//需要设置为false才能回滚,为了不用代理的时候也能生效
			ps = conn.prepareStatement(sql);
			for(int i = 0;i<parameterList.size();i++) {
				Object[] parameters = (Object[])parameterList.get(i);
				this.setParameters(ps, parameters);
				ps.addBatch();
			}
			rowCountArr = ps.executeBatch();
			conn.commit();
		} catch(Exception e){
			e.printStackTrace();
			conn.rollback();
			throw new Exception(e);
		}finally {
			conn.close();
		}	
		return rowCountArr;
	}
	
	//计算记录数，用于分页
	public int count(String sql) throws Exception {
		ResultSet rs = null;
		Connection conn = null;
		try {
			conn = this.getConnection();
			rs = conn.createStatement().executeQuery(sql);
			while(rs.next()) {
				return rs.getInt(1);
			}
		} catch(Exception e){
			e.printStackTrace();
			throw new Exception(e);
		}finally {
			this.close(rs, null, conn);
		}	
		return 0;
	}
	
	//根据sql查询数据
	public List<Map<String, Object>> queryBySql(String sql) throws Exception {
		return queryBySql(sql, null);
	}
	
	public List<Map<String,Object>> queryBySql(String sql, Object[] parameters) throws Exception {
		List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
		
		Connection conn = null;
		PreparedStatement pstm = null;
		ResultSet rs = null;
		try {
			conn = this.getConnection();
			pstm = conn.prepareStatement(sql);
			if(parameters != null) {
				this.setParameters(pstm, parameters);
			}
			rs = pstm.executeQuery();
			this.rsToList(rs, list);
		} catch(Exception e){
			e.printStackTrace();
			throw new Exception(e);
		}finally {
			this.close(rs, pstm, conn);
		}
		return list;
	}
	
	public Map<String,Object> queryById(String sql) throws Exception {
		return queryById(sql, null);
	}
	
	public Map<String,Object> queryById(String sql, Object[] parameters) throws Exception {
		Map<String,Object> map = new HashMap<String,Object>();
		
		Connection conn = null;
		PreparedStatement pstm = null;
		ResultSet rs = null;
		try {
			conn = this.getConnection();
			pstm = conn.prepareStatement(sql);
			if(parameters != null) {
				this.setParameters(pstm, parameters);
			}
			rs = pstm.executeQuery();
			this.rsToMap(rs, map);
		} catch(Exception e){
			e.printStackTrace();
			throw new Exception(e);
		}finally {
			this.close(rs, pstm, conn);
		}
		return map;
	}
	
	public IWebText getJsonDataBySql(String sql) throws Exception {
		JSONObject root = new JSONObject();
		JSONArray jsonArr = new JSONArray();

		Connection conn = null;
		ResultSet rs = null;
		PreparedStatement ps = null;
		try {
			conn = this.getConnection();
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			this.rsToJson(rs, jsonArr);
		} catch(Exception e){
			e.printStackTrace();
			throw new Exception(e);
		}finally {
			this.close(rs, ps, conn);
		}

		root.put("root", jsonArr);
		JsonWebText jsonWebText = new JsonWebText();
		jsonWebText.setJsonObject(root);
		return jsonWebText;
	}
	
	public IWebText getXmlDataBySql(String sql, String pkName) throws Exception {		
		return this.getXmlDataBySql(sql, null, pkName);
	}
	
	protected IWebText getXmlDataBySql(String sql, Object[] parameters, String pkName) throws Exception {		
		XmlDataBean root = new XmlDataBean();
		root.setNameSpace("root");
		root.setId("0");

		Connection conn = null;
		ResultSet rs = null;
		PreparedStatement ps = null;
		try {
			conn = this.getConnection();
			ps = conn.prepareStatement(sql);
			if(parameters != null) {
				this.setParameters(ps, parameters);
			}
			rs = ps.executeQuery();
			this.rsToXml(rs, root, pkName);
		} catch(Exception e){
			e.printStackTrace();
			throw new Exception(e);
		}finally {
			this.close(rs, ps, conn);
		}
		
		DebugUtil.print(root.outWebText());
		return root;
	}
	
	//删除数据
	public IWebText del(JSONObject json) throws Exception {	
		StringWebText swt = new StringWebText();
		
		return swt;
	}
	
	//保存数据
	public IWebText save(JSONObject json) throws Exception {	
		StringWebText swt = new StringWebText();
		
		return swt;
	}
	
	protected void rsToJson(ResultSet rs, JSONArray jsonArr) throws SQLException {
		ResultSetMetaData metaData = rs.getMetaData();
		int colCount = metaData.getColumnCount();
		while (rs.next()) {
			JSONObject jsonData = new JSONObject();

			for (int colIndex = 1; colIndex <= colCount; colIndex++) {
				String colName = metaData.getColumnLabel(colIndex)
						.toUpperCase();
				// int colType = metaData.getColumnType(colIndex);
				Object colValue = rs.getObject(colIndex);
				if(colValue == null) colValue = "";
				jsonData.put(colName, String.valueOf(colValue));
			}
			jsonArr.add(jsonData);
		}
	}
	
	protected void rsToXml(ResultSet rs, XmlDataBean root, String pkName) throws SQLException {
		ResultSetMetaData metaData = rs.getMetaData();
		int colCount = metaData.getColumnCount();
		while (rs.next()) {
			XmlDataBean bean = new XmlDataBean();
			for (int colIndex = 1; colIndex <= colCount; colIndex++) {
				String colName = metaData.getColumnLabel(colIndex).toUpperCase();
				// int colType = metaData.getColumnType(colIndex);
				Object colValue = rs.getObject(colIndex);
				if(colValue == null) colValue = "";
				bean.setAttribute(colName, String.valueOf(colValue));
				if(pkName.equals(colName)) {
					bean.setId(String.valueOf(colValue));
				}
			}
			root.appendChildXmlDataBean(bean);
		}
	}
	
	//多记录转换成List
	protected void rsToList(ResultSet rs, List<Map<String,Object>> list) throws SQLException {
		ResultSetMetaData rsmd = rs.getMetaData();
		int columnCount = rsmd.getColumnCount();
		while(rs.next()){
			Map<String,Object> rowMap = new HashMap<String,Object>();
			for (int i = 1; i <= columnCount; i++) {
				String colName = rsmd.getColumnName(i);
				//String colTypeName = rsmd.getColumnTypeName(i);
				Object colValue = rs.getObject(i);
				rowMap.put(colName, colValue);
			}
			list.add(rowMap);
		}
	}
	
	//单记录转换成Map
	protected void rsToMap(ResultSet rs, Map<String,Object> rowMap) throws SQLException {
		ResultSetMetaData rsmd = rs.getMetaData();
		int columnCount = rsmd.getColumnCount();
		if(rs.next()){
			for (int i = 1; i <= columnCount; i++) {
				String colName = rsmd.getColumnName(i);
				//String colTypeName = rsmd.getColumnTypeName(i);
				Object colValue = rs.getObject(i);
				rowMap.put(colName, colValue);
			}
		}
	}

	protected void setParameters(PreparedStatement ps, Object[] parameters)
			throws Exception {
		for (int i = 0; i < parameters.length; i++) {
			int parameterIndex = i + 1;
			Object param = parameters[i];
			if (param == null) {
				ps.setObject(parameterIndex, null);
			} else if (param instanceof java.sql.Date) {
				java.sql.Date value = (java.sql.Date) param;
				ps.setDate(parameterIndex, value);

			} else if (param instanceof java.util.Date) {
				long time = ((java.util.Date) param).getTime();
				java.sql.Date value = new java.sql.Date(time);
				ps.setDate(parameterIndex, value);
			} else if (param instanceof java.util.Calendar) {
				Calendar c = (Calendar) param;
				java.sql.Date d = new java.sql.Date(c.getTime().getTime());
				ps.setDate(parameterIndex, d, c);
			} else if (param instanceof String) {
				ps.setString(parameterIndex, (String) param);
			} else if (param instanceof CharSequence) {
				String value = param.toString();
				ps.setString(parameterIndex, value);
			} else if (param instanceof char[]) {
				String value = new String((char[]) param);
				ps.setString(parameterIndex, value);
			} else if (param instanceof Character) {
				ps.setString(parameterIndex, String.valueOf(param));
			} else if (param instanceof Integer) {
				int value = ((Integer) param).intValue();
				ps.setInt(parameterIndex, value);
			} else if (param instanceof Short) {
				short value = ((Short) param).shortValue();
				ps.setShort(parameterIndex, value);
			} else if (param instanceof Long) {
				long value = ((Integer) param).longValue();
				ps.setLong(parameterIndex, value);
			} else if (param instanceof BigDecimal) {
				BigDecimal value = (BigDecimal) param;
				ps.setBigDecimal(parameterIndex, value);
			} else if (param instanceof java.sql.Ref) {
				Ref value = (Ref) param;
				ps.setRef(i, value);
			} else if (param instanceof Double) {
				double value = ((Double) param).doubleValue();
				ps.setDouble(parameterIndex, value);
			} else if (param instanceof Float) {
				float value = ((Float) param).floatValue();
				ps.setFloat(parameterIndex, value);
			} else if (param instanceof Boolean) {
				boolean value = ((Boolean) param).booleanValue();
				ps.setBoolean(parameterIndex, value);
			} else if (param instanceof java.sql.Array) {
				ps.setArray(parameterIndex, (java.sql.Array) param);
			} else if (param instanceof java.sql.Time) {
				ps.setTime(parameterIndex, (java.sql.Time) param);
			} else if (param instanceof java.sql.Timestamp) {
				ps.setTimestamp(parameterIndex, (java.sql.Timestamp) param);
			} else if (param instanceof java.net.URL) {
				ps.setURL(parameterIndex, (java.net.URL) param);
			} else if (param instanceof byte[]) {
				ps.setBytes(parameterIndex, (byte[]) param);
			} else if (param instanceof Clob) {
				ps.setClob(parameterIndex, (Clob) param);
			} else if (param instanceof Byte) {
				byte value = ((Byte) param).byteValue();
				ps.setByte(parameterIndex, value);
			} else {
				throw new IllegalArgumentException("未知参数类型: "
						+ param.getClass());
			}
		}
	}
	
	//获取分页数据
	public PageInfo getPageInfo(PageInfo pageInfo) throws Exception {
		
		Condition condition = new Condition();
		condition.setCurPage(Integer.parseInt("1"));
		pageInfo.setCondition(condition);

		List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
		Map<String,Object> map = new HashMap<String,Object>();
		int rowCount = 0;
		
		Connection conn = null;
		PreparedStatement pstm = null;
		ResultSet rs = null;
		try {
			conn = this.getConnection();
			pstm = conn.prepareStatement("select * from SQL_QUERY where id=? ");
			//pstm.setString(1, moduleId);
			rs = pstm.executeQuery();
			this.rsToMap(rs, map);
			
			String sql = (String)map.get("QUERY_SQL");
			condition.setSql(sql);
			Pageable pageUtil = new JdbcPageImpl(pageInfo);
			
			pstm = conn.prepareStatement("select count(*) from (" + sql + ") t ");
			rs = pstm.executeQuery();
			if(rs.next()) {
				rowCount = rs.getInt(1);//从1开始
			}
			pageUtil.setRowCount(rowCount);
			pageInfo = pageUtil.getPageInfo();
			sql = pageInfo.getPageSql();
			pstm = conn.prepareStatement(sql);
			rs = pstm.executeQuery();
			this.rsToList(rs, list);
		} catch(Exception e){
			e.printStackTrace();
			throw new Exception(e);
		}finally {
			this.close(rs, pstm, conn);
		}
		pageInfo.setPageObject(list);
		return pageInfo;
	}
	
	//获取列表的所有数据
	public List<Map<String,Object>> getListData() throws Exception {
		HttpServletRequest request = this.getWebHelper().getRequest();
		
		//从url中传过来
		String tableName = request.getParameter("tableName");
		if(StringUtil.isNull(tableName)) tableName = getTableName();
		request.setAttribute("tableName", tableName);
		
		//获取表的配置信息
		//List<Map<String,Object>> configList = service.queryBySql("select * from SYSMAN_TABLE_CONFIG where TABLE_NAME = '" + tableName + "' order by SHOW_ORDER ");
		List<Map<String,Object>> configList = CacheService.getDataByCacheId("SYSMAN_TABLE_CONFIG", "TABLE_NAME", tableName);
		setDD(null, configList);
		request.setAttribute("configList", configList);
		request.setAttribute("pkName", getPkName(configList));//主键字段名
		
		//扩展按钮
		setButtonMap(tableName);
		
		//组装页面的搜索条件
		String condSql = getCondition(configList);
		condSql += getConditionSql();
		String pid = request.getParameter("pid");
		if(StringUtils.isNotEmpty(pid)) {
			condSql += " and pid='" + pid + "' order by TREE_ORDER ";
			request.setAttribute("pid", pid);
		} else {
			String pidName = request.getParameter("pidName");
			if(StringUtils.isNotEmpty(pidName)) {
				pid = request.getParameter(pidName);
				if(StringUtils.isNotEmpty(pid)) {
					condSql += " and " + pidName + "='" + pid + "' ";
					request.setAttribute(pidName, pid);
					
					String orderName = request.getParameter("orderName");
					if(StringUtils.isNotEmpty(orderName)) {
						condSql += " order by " + orderName;
					}
				}
			}
		}
		condSql += getOrderSql();
		
		//查询表的所有数据
		List<Map<String,Object>> pageList = queryBySql("select * from " + StringUtil.getTableName(tableName) + " where 1=1 " + condSql);
		//翻译数据
		parseDD(pageList, configList);
		
		request.setAttribute("pageList", pageList);
		
		return pageList;
	}
	
	//获取分页数据,用于分页列表页面
	public PageInfo getPageInfo() throws Exception {
		HttpServletRequest request = this.getWebHelper().getRequest();
				
		//从url中传过来
		String tableName = request.getParameter("tableName");
		request.setAttribute("tableName", tableName);
		
		//从请求中获取页码
		String curPage = request.getParameter("curPage");
		if(StringUtils.isEmpty(curPage)) curPage = "1";
		
		//条件对象
		Condition condition = new Condition();
		condition.setCurPage(Integer.parseInt(curPage));
		
		//获取表的配置信息
		//List<Map<String,Object>> configList = service.queryBySql("select * from SYSMAN_TABLE_CONFIG where TABLE_NAME = '" + tableName + "' order by SHOW_ORDER ");
		List<Map<String,Object>> configList = CacheService.getDataByCacheId("SYSMAN_TABLE_CONFIG", "TABLE_NAME", tableName);
		setDD(null, configList);
		request.setAttribute("configList", configList);
		request.setAttribute("pkName", getPkName(configList));
		
		//扩展按钮
		setButtonMap(tableName);
		
		//组装页面的搜索条件
		String condSql = getCondition(configList);
		
		String sql = "select t.* from " + StringUtil.getTableName(tableName) + " t where 1=1 " + condSql;
		condition.setSql(sql);
		
		//分页信息对象
		PageInfo pageInfo = new PageInfo();
		pageInfo.setCondition(condition);
		
		//查询总记录数
		Integer rowCount = count("select count(*) from " + StringUtil.getTableName(tableName) + " where 1=1 " + condSql);
		
		//查询分页数据
		Pageable pageable = new JdbcPageImpl(pageInfo);
		pageable.setRowCount(rowCount);
		String pageSql = pageInfo.getPageSql();
		List<Map<String, Object>> list = queryBySql(pageSql);
		pageInfo.setPageObject(list);
		
		//翻译数据
		parseDD(list, configList);
		request.setAttribute("pageList", list);
		request.setAttribute("pageInfo", pageInfo);
		
		return pageInfo;
	}
	
	protected String getSaveSql(Map<String,Object> map, String tableName) {
		String pk = "";
		String pkName = "";
		boolean isInsert = false;
		StringBuffer sql1 = new StringBuffer();
		StringBuffer sql2 = new StringBuffer();
		
		List<Map<String,Object>> configList = CacheService.getDataByCacheId("SYSMAN_TABLE_CONFIG", "TABLE_NAME", tableName);
		for(Map<String,Object> configMap : configList) {
			String fieldName = (String)configMap.get("FIELD_NAME");//字段名
			String fieldValue = String.valueOf(map.get(fieldName));
			if("null".equals(fieldValue)) fieldValue = "";
			logger.info(fieldName + ":" + fieldValue );
			Integer isPk = (Integer)configMap.get("IS_PK");//是否主键
			String fieldType = (String)configMap.get("FIELD_TYPE");
			if(1 == isPk) {
				pk = fieldValue;
				pkName= fieldName;
				
				if(StringUtils.isEmpty(pk)) {//新增
					pk = IDGeneratorUtil.generateStringID();
					isInsert = true;
				}
				map.put(pkName, pk);
			} else {
				if(isInsert) {//新增
					if(StringUtils.isEmpty(fieldValue)) {
						fieldValue = (String)configMap.get("DEFAULT_VALUE");
						map.put(fieldName, fieldValue);
						if("D".equals(fieldType) && "date".equals(fieldValue)) {//当前日期
							fieldValue = DateUtil.dateToString(new Date());
						}
					}
					sql1.append("," + fieldName);
					sql2.append("," + getSqlByType(fieldType, fieldName, fieldValue, isInsert));
				} else {//修改
					sql1.append("," + fieldName + "=" + getSqlByType(fieldType, fieldName, fieldValue, isInsert));
				}
			}
		}
	
		String sql = "";
		if(isInsert) {//新增
			sql = "insert into " + StringUtil.getTableName(tableName) + "(" + pkName + sql1.toString() + ") values('" + pk + "'" + sql2.toString() + ")"; 
		} else {//修改
			sql = "update " + StringUtil.getTableName(tableName) + " set " + sql1.toString().substring(1) + " where " + pkName + "='" + pk + "'";
		}

		return sql;
	}
	
	//保存
	public Map<String,Object> save() throws Exception {
		HttpServletRequest request = this.getWebHelper().getRequest();
		
		String tableName = request.getParameter("tableName");
		
		Map<String,Object> map = new HashMap<String, Object>();
		List<Map<String,Object>> configList = CacheService.getDataByCacheId("SYSMAN_TABLE_CONFIG", "TABLE_NAME", tableName);
		for(Map<String,Object> configMap : configList) {
			String fieldName = (String)configMap.get("FIELD_NAME");//字段名
			String fieldValue = request.getParameter(fieldName);
			map.put(fieldName, fieldValue);
		}
	
		return save(map, tableName);
	}
	
	//保存
	public Map<String,Object> save(Map<String,Object> map, String tableName) throws Exception {
		String sql = getSaveSql(map, tableName);
		
		String busDefId = (String)map.get("BUS_DEF_ID");
		if(StringUtils.isNotEmpty(busDefId)) {
			Map<String,Object> busDefMap = queryById("select * from " + StringUtil.getTableName("WF_BUS_DEFINITION") + " where BUS_DEF_ID='" + busDefId + "'" );
			String tableName_ = (String)busDefMap.get("TABLE_NAME");
			if(tableName.equals(tableName_)) {
				IWorkFlowService service = (IWorkFlowService) ServiceFactory.getService(new WorkFlowService());
				service.startProcess(map, null);
			}
		}
		
		executeBySql(sql);
		
		return map;
	}
	
	//保存树型数据
	public void saveTreeData() throws Exception {
		HttpServletRequest request = this.getWebHelper().getRequest();
		
		String tableName = request.getParameter("tableName");
		String pid = request.getParameter("pid");
		Map<String,Object> pEntity = null;//父对象
		
		String pk = "";
		String pkName = "";
		boolean isInsert = false;
		StringBuffer sql1 = new StringBuffer();
		StringBuffer sql2 = new StringBuffer();
		List<Map<String,Object>> configList = CacheService.getDataByCacheId("SYSMAN_TABLE_CONFIG", "TABLE_NAME", tableName);
		for(Map<String,Object> configMap : configList) {
			String fieldName = (String)configMap.get("FIELD_NAME");//字段名
			String fieldValue = request.getParameter(fieldName);
			Integer isPk = (Integer)configMap.get("IS_PK");//是否主键
			String fieldType = (String)configMap.get("FIELD_TYPE");
			if(1 == isPk) {
				pk = fieldValue;
				pkName= fieldName;
				
				if(StringUtils.isEmpty(pk)) {//新增
					pk = IDGeneratorUtil.generateStringID();
					isInsert = true;
				}
				
				//根据父ID查询父对象
				if(!"0".equals(pid)) {
					pEntity = queryById("select * from " + StringUtil.getTableName(tableName) + " where " + pkName + "='" + pid + "'" );
				}
			} else {
				if(isInsert) {//新增
					if(StringUtils.isEmpty(fieldValue)) {
						fieldValue = (String)configMap.get("DEFAULT_VALUE");
					}
					if("PID".equals(fieldName)) {//父ID
						fieldValue = pid;
					} else if("PATH".equals(fieldName)) {//层级路径
						String pPath = "0";
						if(!"0".equals(pid)) {
							pPath = (String)pEntity.get("PATH");
						}
						fieldValue = pPath + "," + pk;
					} else if("NODE_TYPE".equals(fieldName)) {//节点类型,初始化为0
						fieldValue = "0";
					} else if("LEVEL".equals(fieldName)) {//层次
						if("0".equals(pid)) {
							fieldValue = "1";
						} else {
							String pPath = (String)pEntity.get("PATH");
							fieldValue = String.valueOf(pPath.split(",").length);
						}
					}
					
					sql1.append("," + fieldName);
					sql2.append("," + getSqlByType(fieldType, fieldName, fieldValue, isInsert));
				} else {//修改
					sql1.append("," + fieldName + "=" + getSqlByType(fieldType, fieldName, fieldValue, isInsert));
				}
			}
		}
	
		String sql = "";
		if(isInsert) {//新增
			sql = "insert into " + StringUtil.getTableName(tableName) + "(" + pkName + sql1.toString() + ") values('" + pk + "'" + sql2.toString() + ")";
			if("0".equals(pid)) {
				executeBySql(sql);
			} else {//更新父节点的节点类型为1
				String psql = "update " + StringUtil.getTableName(tableName) + " set NODE_TYPE=1 where ID='" + pid + "'";
				executeBySql(new String[]{sql,psql});
			}
		} else {//修改
			sql = "update " + StringUtil.getTableName(tableName) + " set " + sql1.toString().substring(1) + " where " + pkName + "='" + pk + "'";
			executeBySql(sql);
		}
		
	}
	
	//根据ID获取数据,用于编辑页面
	public Map<String,Object> getEntityData() throws Exception {
		HttpServletRequest request = this.getWebHelper().getRequest();

		//从url中传过来
		String tableName = request.getParameter("tableName");
		request.setAttribute("tableName", tableName);
		
		//获取表的配置信息
		//List<Map<String,Object>> configList = service.queryBySql("select * from SYSMAN_TABLE_CONFIG where TABLE_NAME = '" + tableName + "' order by SHOW_ORDER ");
		List<Map<String,Object>> configList = CacheService.getDataByCacheId("SYSMAN_TABLE_CONFIG", "TABLE_NAME", tableName);
		request.setAttribute("configList", configList);
		
		//根据ID获取数据
		Map<String,Object> map = new HashMap<String,Object>();
		String id = request.getParameter("id");
		if(StringUtils.isNotEmpty(id)) {
			String pkName = getPkName(configList);
			map = queryById("select * from " + StringUtil.getTableName(tableName) + " where " + pkName + "='" + id + "'" );
		}
		request.setAttribute("entity", map);
		
		//设置数据字典
		setDD(map, configList);
		
		return map;
	}
	
	//根据数据字典翻译数据
	public void parseDD(List<Map<String, Object>> dataList, String tableName) throws Exception {
		List<Map<String,Object>> configList = CacheService.getDataByCacheId("SYSMAN_TABLE_CONFIG", "TABLE_NAME", tableName);
		
		parseDD(dataList, configList);
	}
	
	//根据数据字典翻译数据
	public void parseDD(List<Map<String, Object>> dataList, List<Map<String,Object>> configList) throws Exception {
		for(Map<String, Object> map : dataList) {
			parseDD(map, configList);
		}
	}
	
	//根据数据字典翻译数据
	public void parseDD(Map<String, Object> map, String tableName) throws Exception {
		List<Map<String,Object>> configList = CacheService.getDataByCacheId("SYSMAN_TABLE_CONFIG", "TABLE_NAME", tableName);
		parseDD(map, configList);
	}
	
	//根据数据字典翻译数据
	public void parseDD(Map<String, Object> map, List<Map<String,Object>> configList) throws Exception {
		for(Map<String, Object> configMap : configList) {
			String fieldName = (String)configMap.get("FIELD_NAME");
			String dd = (String)configMap.get("EXPRESSION");
			if(StringUtils.isNotEmpty(dd)) {
				String value = String.valueOf(map.get(fieldName));
				List<Map<String,Object>> dictList = null;
				if(dd.indexOf("select") == -1) {
					dictList = CacheService.getDataByCacheId("SYSMAN_DD", "PID", dd);
				} else {
					dictList = queryBySql(dd);
					for(Map<String,Object> dictMap : dictList) {
						if(dictMap.get("ID") != null) {
							dictMap.put("CODE", dictMap.get("ID"));
						}
						logger.info("ID = " + dictMap.get("ID") + ",CODE = " + dictMap.get("CODE") + ",NAME = " + dictMap.get("NAME"));
					}
				}
				for(Map<String,Object> dictMap : dictList) {
					String dictCode = (String)dictMap.get("CODE");
					if(dictCode == null) dictCode = (String)dictMap.get("ID");
					if(dictCode != null && dictCode.equals(value)) {
						String dictText = (String)dictMap.get("NAME");
						map.put("DD_" + fieldName, dictText);
						break;
					}
				}
			}
		}
	}
	
	//设置搜索条件
	public String getCondition(List<Map<String,Object>> configList) {
		HttpServletRequest request = this.getWebHelper().getRequest();
		
		String condSql = "";
		for(Map<String,Object> map : configList) {
			Integer isSearch = (Integer)map.get("IS_SEARCH");
			isSearch = (isSearch == null) ? 0 : isSearch; 
			if(1 == isSearch) {
				String paraName = (String)map.get("FIELD_NAME");
				String paraValue = request.getParameter(paraName);
				if(StringUtils.isNotEmpty(paraValue)) {
					String type = request.getParameter("FIELD_TYPE");
					//String dd = (String)map.get("EXPRESSION");
					if("I".equals(type) || "F".equals(type)) {//整数或浮点数
						condSql += " and " + paraName + "=" + paraValue;
					} else if("S".equals(type)) {//字符串
						condSql += " and " + paraName + " like '%" + paraValue + "%'";
					} else {
						condSql += " and " + paraName + " like '%" + paraValue + "%'";
					}
				}
				map.put("SEARCH_VALUE", paraValue);
			}
		}
		return condSql;
	}
	
	//设置数据字典
	public void setDD(Map<String,Object> entity, List<Map<String,Object>> configList) throws Exception {
		HttpServletRequest request = this.getWebHelper().getRequest();
		
		for(Map<String,Object> map : configList) {
			//Integer isSearch = (Integer)map.get("IS_SEARCH");
			String dd = (String)map.get("EXPRESSION");
			if(StringUtils.isNotEmpty(dd)) {
				List<Map<String,Object>> dictList = null;
				if(dd.indexOf("select") == -1) {
					dictList = CacheService.getDataByCacheId("SYSMAN_DD", "PID", dd);
				} else {
					dictList = queryBySql(dd);
					for(Map<String,Object> dictMap : dictList) {
						if(dictMap.get("ID") != null) {
							dictMap.put("CODE", dictMap.get("ID"));
						}
						logger.info("ID = " + dictMap.get("ID") + ",CODE = " + dictMap.get("CODE") + ",NAME = " + dictMap.get("NAME"));
					}
				}
				map.put("OPTIONS", dictList);
				
				String paraName = (String)map.get("FIELD_NAME");
				String paraValue = "";
				if(entity != null && !entity.isEmpty()) {//从实体中获取值
					paraValue = String.valueOf(entity.get(paraName));
				} else {//从页面条件中获取值
					paraValue = request.getParameter(paraName);
				}
				
				//需要循环所有,防止前面的缓存
				for(Map<String,Object> dictMap : dictList) {
					String dictCode = (String)dictMap.get("CODE");
					if(dictCode == null) dictCode = (String)dictMap.get("ID");
					if(dictCode != null && paraValue != null && dictCode.equals(paraValue)) {
						dictMap.put("selected", "selected");
					} else {
						dictMap.put("selected", "");
					}
				}
			}
		}
	}
	
	public void setButtonMap(String tableName) throws Exception {
		HttpServletRequest request = this.getWebHelper().getRequest();
		
		Map<String,Object> buttonMap = null; 
		String menuId = request.getParameter("menuId");
		if(StringUtils.isNotEmpty(menuId)) {
			Map<String,Object> menuMap = queryById("select * from " + StringUtil.getTableName("SYSMAN_RIGHT") + " where ID='" + menuId + "'");
			String menuCode = (String)menuMap.get("RIGHT_CODE");
			if(StringUtils.isNotEmpty(menuCode)) {
				buttonMap = CacheService.getDataById("SYSMAN_DD", "CODE", menuCode + "_BUTTON");
				String buttonPage = (String)buttonMap.get("NAME");
				if(StringUtil.isNull(buttonPage)) {
					buttonMap = CacheService.getDataById("SYSMAN_DD", "CODE", tableName + "_BUTTON");
				}
			} else {
				buttonMap = CacheService.getDataById("SYSMAN_DD", "CODE", tableName + "_BUTTON");
			}
		} else {
			buttonMap = CacheService.getDataById("SYSMAN_DD", "CODE", tableName + "_BUTTON");
		}
		request.setAttribute("buttonMap", buttonMap);
	}
	
	public String getSqlByType(String fieldType, String fieldName, String value, Boolean isInsert) {
		if("CREATE_TIME".equals(fieldName)) {//创建时间
			if(isInsert) {
				return "'" + DateUtil.dateToString(new Date()) + "'";
			} else {
				return fieldName;
			}
		} else if("MODIFY_TIME".equals(fieldName)) {//最近修改时间
			return "'" + DateUtil.dateToString(new Date()) + "'";
		} else if(StringUtils.isEmpty(value)) {
			return null;
		} else if("S".equals(fieldType) || "D".equals(fieldType)) {
			return "'" + value + "'";
		} else {
			return value;
		}
	}
	
	//从配置信息中获取主键字段名
	public String getPkName(List<Map<String,Object>> configList) {
		String pkName = "";
		for(Map<String,Object> configMap : configList) {
			if("1".equals(String.valueOf(configMap.get("IS_PK")))) {
				pkName = (String)configMap.get("FIELD_NAME");
				break;
			}
		}
		return pkName;
	}
	
	public static void main(String[] args) throws Exception {
		IService service = (IService) ServiceFactory.getService(null);
		
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("NAME", "test");
		service.save(map, "AD_CASE");
	}
	
}
